package com.kb.design.service.impl.chart;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kb.design.constant.Constants;
import com.kb.design.dto.QueryChartDTO;
import com.kb.design.entity.*;
import com.kb.design.enums.DesignStatus;
import com.kb.design.enums.ProjectStatus;
import com.kb.design.mapper.postgreSQL.*;
import com.kb.design.service.AdminHomeService;
import com.kb.design.service.CustomUserService;
import com.kb.design.service.DeptService;
import com.kb.design.service.chart.GeneralHomeService;
import com.kb.design.util.DateUtils;
import com.kb.design.vo.chart.MonthlyPerformanceVO;
import com.kb.design.vo.chart.OrderDataVO;
import com.kb.design.vo.chart.ProjectNodeInfoChartVO;
import org.aspectj.weaver.ast.Var;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@DS("slave-1")
public class GeneralHomeServiceImpl implements GeneralHomeService {

    @Resource
    private ProjectMapper projectMapper;
    @Resource
    private ChartMapper chartMapper;
    @Resource
    private CustomUserMapper userMapper;
    @Resource
    private DeptService deptService;
    @Resource
    private DesignDeptMapper designDeptMapper;
    @Resource
    private DesignPostMapper postMapper;
    @Resource
    private DesignBonusDistributionMapper bonusDistributionMapper;
    @Resource
    private BonusConfigMapper bonusConfigMapper;

    @Override
    public Map<String, Object> queryPerformanceInfo(QueryChartDTO queryChartDTO) {
        Map<String, Object> result = new HashMap<>();
        //获取上个月时间
        LocalDate[] firstAndLastDayOfMonth = DateUtils.getFirstAndLastDayOfLastMonth();
        queryChartDTO.setStart(firstAndLastDayOfMonth[0]);
        queryChartDTO.setEnd(firstAndLastDayOfMonth[1]);
        queryChartDTO.setRelevantResponsiblePerson(queryChartDTO.getCreateBy());
        Map<String, Object> projectBonusAllocation = bonusDistributionMapper.getProjectBonusAllocation(queryChartDTO);
        Integer projectCount = bonusDistributionMapper.getProjectCount(queryChartDTO);
        //判断当前人是否是部门负责人
        List<DesignDept> deptLeader = deptService.isDeptLeader(queryChartDTO.getCreateBy());
        BigDecimal totalPin = BigDecimal.ZERO;

        if (!CollectionUtils.isEmpty(deptLeader)) {
            for (DesignDept designDept : deptLeader) {
                List<DesignDept> deptList = deptService.queryAllDept(designDept.getDeptId());
                List<Long> longs = deptList.stream().map(DesignDept::getDeptId).collect(Collectors.toList());
                LambdaQueryWrapper<CustomUser> wrapper = Wrappers.lambdaQuery();
                wrapper.in(CustomUser::getDeptId, longs).eq(CustomUser::getDelFlag, Constants.DEL_FLAG_NO);
                List<CustomUser> userList = userMapper.selectList(wrapper);
                //查询这些人的总pin数之和 即为部门的pin数
                queryChartDTO.setRelevantResponsiblePerson(userList.stream().map(CustomUser::getCode).collect(Collectors.joining(",")));
                Map<String, Object> allocation = bonusDistributionMapper.getProjectBonusAllocation(queryChartDTO);
                if (allocation != null) {
                    Object pinObj = allocation.get("pin");
                    totalPin = totalPin.add((BigDecimal) pinObj);
                }
            }
            //总pin数 * 系数 = 部门绩效奖金
            BonusConfig config = bonusConfigMapper.getBonusConfigById(queryChartDTO.getCreateBy(), 1);
            BigDecimal designBonus = BigDecimal.ZERO;
            if (config != null) {
                designBonus = config.getDesignBonus().divide(BigDecimal.valueOf(100));
            }
            result.put("deptBonus", designBonus.multiply(totalPin));
        }
        //订单奖金  区域系数
        BigDecimal salNum = BigDecimal.ZERO;
        BonusConfig config = bonusConfigMapper.getBonusConfigById(queryChartDTO.getCreateBy(), 2);
        if (config != null) {
            salNum = config.getSalesCommission().divide(BigDecimal.valueOf(100));
            //获取已立项订单
            queryChartDTO.setRelevantResponsiblePerson(queryChartDTO.getCreateBy());
            //订单的数据还需要过滤区域  区域数据从配置里面取 和订单的区域字段eq
            queryChartDTO.setSalesArea(config.getSalesArea());
            BigDecimal orderBonus = bonusDistributionMapper.getOrderBonus(queryChartDTO);
            BigDecimal bigDecimal = BigDecimal.ZERO;
            if (orderBonus != null) {
                bigDecimal = salNum.multiply(orderBonus).setScale(0, RoundingMode.HALF_UP);
            }
            result.put("orderBonus", bigDecimal);
        }
        if (projectBonusAllocation != null) {
            result.put("pin", projectBonusAllocation.get("pin"));
            result.put("bonus", projectBonusAllocation.get("bonus"));
        }
        result.put("projectCount", projectCount);
        return result;
    }

    @Override
    public Map<String, Object> projectNumberCount(QueryChartDTO queryChartDTO) {
        String createBy = queryChartDTO.getCreateBy();
        Map<String, Object> result = new HashMap<>();
        //在制项目统计  查询所有未完成 和 进行中的项目 一次性查询 减少性能损耗 和当前登录人相关的数据
        LambdaQueryWrapper<DesignProject> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.isNull(DesignProject::getCompletionTime).eq(DesignProject::getProjectStatusAuxiliary, ProjectStatus.IN_PROGRESS.getIndex());
        List<DesignProject> projectList = projectMapper.selectList(queryWrapper);
        //设计中的项目数 status为20 且projectStatusAuxiliary为10
        List<DesignProject> collect = projectList.stream().filter(project -> Objects.equals(project.getStatus(), DesignStatus.DESIGN.getIndex())
                && Objects.equals(project.getProjectStatusAuxiliary(), ProjectStatus.IN_PROGRESS.getIndex())).collect(Collectors.toList());
        long count = collect.stream().count();
        //pin数统计 根据projectId和createBy参数 查询design_bonus_distribution表的pin_num 就和
//        long designPin = this.sumPinNumByProjectIdAndField0(collect,createBy);
        BigDecimal designPin = collect.stream()
                .map(DesignProject::getPinAmount)
                .filter(Objects::nonNull) // 避免 null 值导致计算异常
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        //待检查项目数 状态是检查 且check_person_list 数组字段有当前登录人工号
        String currentUserCode = queryChartDTO.getCreateBy();
        Integer currentUserCodeInt = Integer.valueOf(currentUserCode);
        List<DesignProject> checkProjectList = projectList.stream()
                .filter(project ->
                        Objects.equals(project.getStatus(), DesignStatus.CHECK.getIndex())
                                && project.getCheckPersonList() != null
                                && project.getCheckPersonList().contains(currentUserCodeInt)
                )
                .collect(Collectors.toList());
        long pendingCheckCount = checkProjectList.stream().count();
        BigDecimal checkPin = checkProjectList.stream()
                .map(DesignProject::getPinAmount)
                .filter(Objects::nonNull) // 避免 null 值导致计算异常
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        //奖金待确认项目数  状态是 WAITING_BONUS_CONFIRMATION 且bonus_person数组有当前登录人工号
        List<DesignProject> bonusProjectList = projectList.stream()
                .filter(project ->
                        Objects.equals(project.getStatus(), DesignStatus.WAITING_BONUS_CONFIRMATION.getIndex())
                                && project.getBonusPerson() != null
                                && project.getBonusPerson().contains(currentUserCodeInt)
                )
                .collect(Collectors.toList());
        long bonusProjectCount = bonusProjectList.stream().count();
        BigDecimal bonusPin = bonusProjectList.stream()
                .map(DesignProject::getPinAmount)
                .filter(Objects::nonNull) // 避免 null 值导致计算异常
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        //暂停项目数  projectStatusAuxiliary为0
        List<DesignProject> stopProjectList = projectList.stream().filter(project -> Objects.equals(project.getProjectStatusAuxiliary(), ProjectStatus.STOP.getIndex())).collect(Collectors.toList());
        long stopProjectCount = stopProjectList.stream().count();
        BigDecimal stopPin = stopProjectList.stream()
                .map(DesignProject::getPinAmount)
                .filter(Objects::nonNull) // 避免 null 值导致计算异常
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //饱和度  在线项目 / 目标数
        //projectStatusAuxiliary为10的数据为设计中的项目数 统计这些项目的所有pin数 求和
        BigDecimal totalPinAmount = projectList.stream().filter(project -> Objects.equals(project.getProjectStatusAuxiliary(), ProjectStatus.IN_PROGRESS.getIndex())).map(DesignProject::getPinAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        CustomUser user = userMapper.queryUserByCode(queryChartDTO.getCreateBy());
        BigDecimal saturationRate = BigDecimal.ZERO;
        if (Objects.nonNull(user) && Objects.nonNull(user.getTargetPin())){
             saturationRate = totalPinAmount.divide(user.getTargetPin(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP);
        }

        result.put("saturation", saturationRate);
        result.put("stopProjectCount", stopProjectCount);
        result.put("stopPin", stopPin);

        result.put("bonusProjectCount", bonusProjectCount);
        result.put("bonusPin", bonusPin);

        result.put("checkProjectCount", pendingCheckCount);
        result.put("checkPin", checkPin);

        result.put("designProjectCount", count);
        result.put("designPin", designPin);
        return result;
    }
    //计算pin数
    public long sumPinNumByProjectIdAndField0(List<DesignProject> collect, String field0) {
        long designPin = 0;
        if (CollectionUtils.isNotEmpty(collect)) {
            List<Long> projectIdList = collect.stream()
                    .map(DesignProject::getId)
                    .collect(Collectors.toList());
            Long result = chartMapper.sumPinNumByProjectIdAndField0(projectIdList, field0);
            return result == null ? 0L : result;
        }
        return designPin;
    }
    @Override
    public List<MonthlyPerformanceVO> getMonthlyPerformanceByUserCode(QueryChartDTO queryChartDTO) {
        List<MonthlyPerformanceVO> result = new ArrayList<>();
        List<Map<String, Object>> lmapList = chartMapper.getMonthlyPerformanceByUserCode(queryChartDTO.getCreateBy(), queryChartDTO.getYear());
        for (int i = 1; i <= 12; i++) {
            MonthlyPerformanceVO monthlyPerformanceVO = new MonthlyPerformanceVO();
            int size = lmapList.size();
            if (size > 0) {
                for (int j = 0; j < size; j++) {
                    Map<String, Object> stringObjectMap = lmapList.get(j);
                    if (stringObjectMap.get("month") != null && stringObjectMap.get("month").equals(BigDecimal.valueOf(i))) {
                        monthlyPerformanceVO.setTotalBonus((BigDecimal) stringObjectMap.get("total_bonus"));
                        monthlyPerformanceVO.setTotalPin((BigDecimal) stringObjectMap.get("total_pin"));
                    } else {
                        monthlyPerformanceVO.setTotalBonus(BigDecimal.ZERO);
                        monthlyPerformanceVO.setTotalPin(BigDecimal.ZERO);
                    }
                }
            } else {
                monthlyPerformanceVO.setTotalBonus(BigDecimal.ZERO);
                monthlyPerformanceVO.setTotalPin(BigDecimal.ZERO);
            }
            result.add(monthlyPerformanceVO);
        }
        return result;
    }
}
